package io.jcode;

import io.jcode.codegen.Generator;
import io.jcode.codegen.JbootGenerator;
import io.jcode.codegen.JfinalGenerator;
import io.jcode.codegen.utils.CodeType;
import io.jcode.codegen.utils.DbUtils;
import io.jcode.codegen.utils.MetaBuilder;
import com.jfinal.kit.StrKit;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.util.Arrays;

///**
// * Goal which generate jboot code.
// *
// * @goal generate
// *
// * @phase process-sources
// *
// */
@Mojo(name = "generate")
@Execute(goal = "generate")
public class GeneratorMojo extends AbstractMojo {

    @Parameter( defaultValue = "${project}", readonly = true )
    private MavenProject project;

    @Parameter(property = "type", defaultValue = "jboot", readonly = true )
    private String type;

    @Parameter(property = "dbType", readonly = true, required = true)
    private String dbType;

    @Parameter(property = "dbUrl", readonly = true, required = true)
    private String dbUrl;

    @Parameter(property = "dbUser", readonly = true, required = true)
    private String dbUser;

    @Parameter(property = "dbPassword", readonly = true, required = true)
    private String dbPassword;

    @Parameter(property = "basePackage", readonly = true)
    private String basePackage;

    @Parameter(property = "codeType", defaultValue = "ALL")
    private CodeType codeType;

    @Parameter(property = "tablePrefix")
    String tablePrefix;

    @Parameter(property = "excludeTables")
    String[] excludeTables;

    public void execute() throws MojoExecutionException, MojoFailureException {
        System.out.printf("Start to generate %s's %s %s code.\n",
                project.getName(), type, codeType.name());
        if(StrKit.isBlank(basePackage)) {
            basePackage = project.getGroupId();
            basePackage = StrKit.firstCharToLowerCase(basePackage);
        }
        boolean isPackageRule = basePackage.matches("^[_\\w]+(\\.?[_0-9A-Za-z]*)*");
        if (!isPackageRule) {
            throw new IllegalArgumentException("the base page naming is illegal: " + basePackage);
        }
        StringBuilder sourceBaskDir = new StringBuilder();
        sourceBaskDir.append(project.getCompileSourceRoots().get(0));

        String rootOutputDir = sourceBaskDir.toString();

        ComboPooledDataSource dataSource = DbUtils.getDatasource(dbUrl, dbUser, dbPassword);

        try {
            MetaBuilder metaBuilder = new MetaBuilder(dataSource, tablePrefix);
            metaBuilder.addExcludedTable(excludeTables);

            Generator generator;
            if(type.equalsIgnoreCase("jfinal")) {
                generator = new JfinalGenerator(dataSource, rootOutputDir, basePackage);
                ((JfinalGenerator) generator).setMetaBuilder(metaBuilder);
            } else {
                generator = new JbootGenerator(codeType, rootOutputDir, basePackage, metaBuilder);
            }
            generator.generate();
        } finally {
            if(dataSource != null) {
                dataSource.close();
            }
        }
    }
}
